package userlogic

import (
	"context"

	"go-zero-admin/apps/system/cmd/rpc/internal/svc"
	"go-zero-admin/apps/system/cmd/rpc/syspb"
	"go-zero-admin/apps/system/model"
	"go-zero-admin/pkg/constant"
	"go-zero-admin/pkg/tool"
	"go-zero-admin/pkg/xerr"

	"github.com/jinzhu/copier"
	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
)

type GetUserByAccountLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewGetUserByAccountLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserByAccountLogic {
	return &GetUserByAccountLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *GetUserByAccountLogic) GetUserByAccount(in *syspb.GetUserByAccountReq) (*syspb.GetUserByAccountResp, error) {
	if in.GetUserName() == "" || in.GetPassword() == "" {
		return nil, errors.Wrapf(xerr.NewErrMsg("获取用户信息失败：参数缺失"),
			tool.GetErrMsgFormat("get account"), "params is not existed", in)
	}

	// 根据账户获取用户数据 根据用户名、手机号、邮箱分别登陆获取用户信息
	user, err := l.svcCtx.SysUserModel.FindOneByUserName(l.ctx, in.GetUserName())
	if user == nil {
		user, err = l.svcCtx.SysUserModel.FindOneByMobile(l.ctx, in.GetUserName())
		if user == nil {
			user, err = l.svcCtx.SysUserModel.FindOneByUserEmail(l.ctx, in.GetUserName())
			if err != nil {
				return nil, errors.Wrapf(xerr.NewErrFindOneCode(err, model.ErrNotFound),
					tool.GetErrMsgFormat("get account"), err, in)
			}
		}
	}

	// 验证密码
	if tool.EncryptPassword(in.GetPassword(), user.UserSalt) != user.UserPassword {
		return nil, errors.Wrapf(xerr.NewErrMsg("获取用户信息失败：账号密码错误"),
			tool.GetErrMsgFormat("get account"), "account or password is error", in)
	}
	//账号状态
	if user.UserStatus == constant.UserStatusDis {
		return nil, errors.Wrapf(xerr.NewErrMsg("获取用户信息失败：账号已被冻结"),
			tool.GetErrMsgFormat("get account"), "account has frozened", in)
	} else if user.UserStatus == constant.UserStatusNoVail {
		return nil, errors.Wrapf(xerr.NewErrMsg("获取用户信息失败：账号未验证"),
			tool.GetErrMsgFormat("get account"), "account not verified", in)
	}

	var data syspb.SysUser
	_ = copier.Copy(&data, user)

	return &syspb.GetUserByAccountResp{One: &data}, nil
}
